﻿/*
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
*/

#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "halls_of_stone.h"
#include "ScriptedEscortAI.h"
#include "SpellScript.h"
#include "Player.h"
#pragma execution_character_set("utf-8")

#define GOSSIP_ITEM_1		"布莱恩, 这是我们的荣幸!"
#define GOSSIP_ITEM_2		"布莱恩, 我们出发吧,历史课上够啰!"
#define GOSSIP_ITEM_3		"我们没有时间了, 现在, 我们一定要坚持下去."
#define TEXT_ID_START		13100
#define YELL_AGGRO			"你很快就会死了!"

enum NPCs
{
	NPC_DARK_RUNE_PROTECTOR			= 27983,
	NPC_DARK_RUNE_STORMCALLER		= 27984,
	NPC_IRON_GOLEM_CUSTODIAN		= 27985,
	NPC_DARK_MATTER_TRIGGER			= 28237,
	NPC_SEARING_GAZE_TRIGGER		= 28265,
};

enum Misc
{
	// BRANN EVENT
	SPELL_GLARE_OF_THE_TRIBUNAL		= 50988,
	SPELL_GLARE_OF_THE_TRIBUNAL_H	= 59870,
	SPELL_DARK_MATTER_VISUAL		= 51001,
	SPELL_DARK_MATTER				= 51012,
	SPELL_DARK_MATTER_H				= 59868,
	SPELL_SEARING_GAZE				= 51136,
	SPELL_SEARING_GAZE_H			= 59867,

	// DARK RUNE PROTECTOR
	SPELL_DRP_CHARGE				= 22120,
	SPELL_DRP_CLEAVE				= 42724,

	// DARK RUNE STORMCALLER
	SPELL_DRS_LIGHTING_BOLT			= 12167,
	SPELL_DRS_LIGHTING_BOLT_H		= 59863,
	SPELL_DRS_SHADOW_WORD_PAIN		= 15654,
	SPELL_DRS_SHADOW_WORD_PAIN_H	= 59864,

	// IRON GOLEM CUSTODIAN
	SPELL_IGC_CRUSH_ARMOR			= 33661,
	SPELL_IGC_GROUND_SMASH			= 12734,
	SPELL_IGC_GROUND_SMASH_H		= 59865,

	// ACTIONS
	ACTION_START_EVENT				= 0,
	ACTION_START_TRIBUNAL			= 1,
	ACTION_GO_TO_SJONNIR			= 2,
	ACTION_START_SJONNIR_FIGHT		= 3,
	ACTION_SJONNIR_DEAD				= 4,
	ACTION_ENTEREVADEMODE			= 5,
	ACTION_WIPE_START				= 6,

	// QUESTS
	QUEST_HALLS_OF_STONE			= 13207,
};

enum events
{
	// BRANN
	EVENT_KADDRAK_HEAD			= 1,
	EVENT_MARNAK_HEAD			= 2,
	EVENT_ABEDNEUM_HEAD			= 3,
	EVENT_SUMMON_MONSTERS		= 4,
	EVENT_TRIBUNAL_END			= 5,
	EVENT_GO_TO_SJONNIR			= 6,
	EVENT_END					= 7,
	EVENT_KADDRAK_VISUAL		= 8,
	EVENT_MARNAK_VISUAL			= 9,
	EVENT_ABEDNEUM_VISUAL		= 10,
	EVENT_KADDRAK_SWITCH_EYE	= 11,

	// DARK RUNE PROTECTOR
	EVENT_DRP_CHARGE			= 15,
	EVENT_DRP_CLEAVE			= 16,

	// DARK RUNE STORMCALLER
	EVENT_DRS_LIGHTNING_BOLD	= 20,
	EVENT_DRS_SHADOW_WORD_PAIN	= 21,

	// IRON GOLEM CUSTODIAN
	EVENT_IGC_CRUSH				= 30,
	EVENT_IGC_GROUND_SMASH		= 31,
};

struct Yells
{
	uint32 sound;
	const char* text;
	uint32 creature, timer;
};

static Yells Conversation[]=
{
	{14259, "是找出答案的时候了!让好戏开演吧!", NPC_BRANN, 0},
	{14247, "和我一起享受这时刻. 一切...马上就要真相大白了. 好了, 我们开始吧!", NPC_BRANN, 5000},
	{14248, "帮我看着外头!我只要三两下就可以搞定这玩意--", NPC_BRANN, 17000},
	{13765, "警告:无法辨识生命体样式. 档案处理终止. 继续干涉将会导致锁定反应.", NPC_ABEDNEUM, 20500},
	{14249, "噢, 听起来真不妙. 咱们可能碰上了一两个小麻烦...", NPC_BRANN, 32000},
	{13756, "安全机制突破中, 史实数据分析已调至低优先队列, 启动反制程序.", NPC_KADDRAK, 37000},
	{14250, "啊, 你想玩硬的是吗?嗯?这我可是太擅长了!", NPC_BRANN, 49000},
	{14251, "再几分钟我就--", NPC_BRANN, 100000},
	{13761, "已超出威胁指数标准. 天界数据库已中止. 安全等级已提升.", NPC_MARNAK, 105000},
	{14252, "提升?这算好消息吗?", NPC_BRANN, 116000},
	{14253, "所以说问题在这啰!这下可有进展了...", NPC_BRANN, 195000},
	{13767, "威胁指数过高. 已转移无效的分析. 启动清洁处理协议.", NPC_ABEDNEUM, 205000},
	{14254, "等一下!只要我不准, 你就别想清理掉任何人!", NPC_BRANN, 215000},
	{14255, "哈!看来我的金手指还是宝刀未老!现在让咱们继续--", NPC_BRANN, 295000}, 
	{13768, "警告:安全性系统自动修复装置已被关闭. 开始内存内容消除与... ", NPC_ABEDNEUM, 303000},
	//The fight is completed at this point.
	{14256, "消除?不不不不...我刚刚--啊哈, 这招应该行的通...", NPC_BRANN, 310000},
	{13769, "系统登入. 生命体样式已确认. 欢迎, 布莱恩·铜须. 是否查询?", NPC_ABEDNEUM, 321000},
	{14263, "查询?不然你以为我来干嘛, 喝下午茶?快把秘密吐出来吧!", NPC_BRANN, 329000},
	{14264, "告诉我矮人是怎么来的, 从头开始讲!", NPC_BRANN, 336000},
	{13770, "检索上古数据...已取得. 初始时, 土灵被创造出来是为了--", NPC_ABEDNEUM, 342000},
	{14265, "对, 对...我知道土灵是用石头做的, 用来塑造世界的地下深处. 但是那个异常是怎么回事?基质失序是什么玩意的?", NPC_BRANN, 348000},
	{13771, "检索中...在初始创造阶段的演化循环中, 艾泽拉斯遭受寄生性死灵宿体的侵扰.", NPC_ABEDNEUM, 360000},
	{14266, "噬命什么鬼呀--天杀的能不能讲人话?", NPC_BRANN, 373500},
	{13772, "“称号:上古诸神. 上古诸神感染了土灵在内整个毫无防御的系统. 这种母体结构失序的情况被称为“血肉诅咒”. 而这失序的情形与日俱增.", NPC_ABEDNEUM, 380000},
	{14267, "上古之神, 嗯?所以他们对土灵下了这什么血肉诅咒...然后呢?", NPC_BRANN, 399500},
	{13757, "检索中...创造者抵达以灭绝共生感染. 测量结果显示上古诸神感染已转变为恶性. 消灭寄生体将导致宿主死亡--", NPC_KADDRAK, 406000},
	{14268, "假如他们杀死上古之神, 艾泽拉斯也会跟着毁灭...", NPC_BRANN, 424000},
	{13758, "正确. 创造者消灭寄生威胁, 将其限制于寄主身上. 意志熔炉与其它系统受命创造新土灵. 设置警卫, 指派守卫者.", NPC_KADDRAK, 429000},
	{14269, "什么守卫者?", NPC_BRANN, 449000},
	{13759, "称谓:瓦尼尔和艾塞尔. 通用名称为风暴巨人和大地巨人. 监控者洛肯设定为至高者. 守护巨龙被指派负责监控艾泽拉斯的演化情况.", NPC_KADDRAK, 452000},
	{14270, "瓦尼尔和艾塞尔...很好, 所以, 意志熔炉开始制造新的土灵...那旧的呢?", NPC_BRANN, 471000},
	{13762, "查询额外关连背景:随着瓦尼尔跟艾塞尔间的全面战斗--", NPC_MARNAK, 482000},
	{14271, "暂停一下!瓦尼尔和艾塞尔爆发了战争?为什么?", NPC_BRANN, 489000},
	{13763, "不详. 数据显示, 全面战争是由首席管理官洛肯发起, 他消灭了所有残余的瓦尼尔和艾塞尔, 并结束了冲突. 接着, 首席管理官洛肯终止了土灵、巨人和维库人等数个原种生物的演化, 并将他们封存在指定设施中.", NPC_MARNAK, 494000},
	{14272, "这个“洛肯”听起来可真像个坏蛋. 幸好咱们不用再担心这家伙了. 所以说...如果我没搞错的话, 原始的土灵最终从封存中醒了过来, 那时候这失序什么玩意的已经将他们转变成了矮人. 或者说...是矮人的祖先.", NPC_BRANN, 519000},
	{13764, "本质上的确如此.", NPC_MARNAK, 543000},
	{14273, "好吧...我得消化一下. 我需要很多时间来把这些信息通通整理好. 谢谢你啊.", NPC_BRANN, 549000},
	{13773, "确认, 布莱恩·铜须. 程序终结.", NPC_ABEDNEUM, 559000},
	{0, "我想该瞧瞧靠近入口那扇门后面是什么了. 我要偷偷潜入那边, 安静而完美. 到门那边跟我会合, 我会把我们都给弄进去.", NPC_BRANN, 574000},
};

class brann_bronzebeard : public CreatureScript
{
public:
    brann_bronzebeard() : CreatureScript("brann_bronzebeard") { }

	bool OnGossipHello(Player *player, Creature *pCreature)
	{
		InstanceScript* pInstance = (pCreature->GetInstanceScript());

		player->TalkedToCreature(pCreature->GetEntry(), pCreature->GetGUID());
		player->PrepareGossipMenu(pCreature, 0, true);
		if (pInstance)
		{
			uint32 brann = pInstance->GetData(BRANN_BRONZEBEARD);
			switch (brann)
			{
			case 1:
				player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
				break;
			case 2:
				player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
				break;
			case 3:
				player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
				break;
			case 4:
				player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
				break;
			default: break;
			}

		}
		player->SEND_GOSSIP_MENU(TEXT_ID_START, pCreature->GetGUID());
		return true;
	}

	bool OnGossipSelect(Player *player, Creature *pCreature, uint32 sender, uint32 action )
	{
		if (action)
		{
			switch (action)
			{
			case GOSSIP_ACTION_INFO_DEF+1:
				pCreature->AI()->DoAction(ACTION_START_EVENT);
				player->CLOSE_GOSSIP_MENU();
				break;
			case GOSSIP_ACTION_INFO_DEF+2:
				pCreature->AI()->DoAction(ACTION_START_TRIBUNAL);
				player->CLOSE_GOSSIP_MENU();
				break;
			case GOSSIP_ACTION_INFO_DEF+3:
				pCreature->AI()->DoAction(ACTION_GO_TO_SJONNIR);
				player->CLOSE_GOSSIP_MENU();
				break;
			case GOSSIP_ACTION_INFO_DEF+4:
				pCreature->AI()->DoAction(ACTION_WIPE_START);
				player->CLOSE_GOSSIP_MENU();
				break;
			}
		}
		return true;
	}

    CreatureAI* GetAI(Creature* pCreature) const
    {
        return new brann_bronzebeardAI (pCreature);
    }

	struct brann_bronzebeardAI : public npc_escortAI
	{

		brann_bronzebeardAI(Creature *c) : npc_escortAI(c), summons(me)
		{   
			AbedneumGUID = MarnakGUID = KaddrakGUID = 0;
			pInstance = c->GetInstanceScript();
		}

		InstanceScript* pInstance;
		EventMap events;
		SummonList summons;
		uint64 AbedneumGUID;
		uint64 MarnakGUID;
		uint64 KaddrakGUID;
		uint8 WaveNum;

		bool TalkEvent;
		uint32 SpeechCount, SpeechPause;

		void DespawnHeads()
		{
			Creature *cr;
			if (cr = GetAbedneum()) cr->DespawnOrUnsummon();
			if (cr = GetMarnak()) cr->DespawnOrUnsummon();
			if (cr = GetKaddrak()) cr->DespawnOrUnsummon();	
			SwitchHeadVisaul(0x7, false);
		}

		void SwitchHeadVisaul(uint8 headMask, bool activate)
		{
			if (!pInstance)
				return;

			GameObject *go = NULL;
			if (headMask & 0x1) // Kaddrak
				if (go = me->GetMap()->GetGameObject(pInstance->GetData64(GO_KADDRAK)))
					activate ? go->SendCustomAnim(0) : go->SetGoState(GO_STATE_READY);

			if (headMask & 0x2) // Marnak
				if (go = me->GetMap()->GetGameObject(pInstance->GetData64(GO_MARNAK)))
					activate ? go->SendCustomAnim(0) : go->SetGoState(GO_STATE_READY);

			if (headMask & 0x4) // Abedneum
				if (go = me->GetMap()->GetGameObject(pInstance->GetData64(GO_ABEDNEUM)))
					activate ? go->SendCustomAnim(0) : go->SetGoState(GO_STATE_READY);
		}

		void ResetEvent()
		{
			if (GameObject *tribunal = ObjectAccessor::GetGameObject(*me, pInstance->GetData64(GO_TRIBUNAL_CONSOLE)))
				tribunal->SetGoState(GO_STATE_READY);

			events.Reset();
			summons.DespawnAll();
			DespawnHeads();

			WaveNum = 0;
			SpeechCount = 0;
			SpeechPause = 0;
			TalkEvent = false;
		}

		void WaypointReached(uint32 id);
		void InitializeEvent();

		Creature* GetAbedneum() { return ObjectAccessor::GetCreature(*me, AbedneumGUID); }
		Creature* GetMarnak() { return ObjectAccessor::GetCreature(*me, MarnakGUID); }
		Creature* GetKaddrak() { return ObjectAccessor::GetCreature(*me, KaddrakGUID); }

		void MoveInLineOfSight(Unit* pWho) { }
		void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
		{ 
			if (damage && pInstance)
				pInstance->SetData(DATA_BRANN_ACHIEVEMENT, false);
		}
		
		void Reset() 
		{
			RemoveEscortState(0x7); // all states
			SetDespawnAtFar(false);
			SetDespawnAtEnd(false);
			ResetEvent();

			me->setFaction(35);
			me->SetReactState(REACT_PASSIVE);
			me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);

			if(pInstance)
			{
				pInstance->SetData(BRANN_BRONZEBEARD, 1);
				pInstance->SetData(DATA_BRANN_ACHIEVEMENT, true);
				
				if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE)
					pInstance->SetData(BRANN_BRONZEBEARD, (pInstance->GetData(BOSS_SJONNIR) == DONE) ? 5 : 4);
			}
		}

		void DoAction(int32 action)
		{
			switch (action)
			{
				case ACTION_START_EVENT:
					Start(false, true, 0, 0, true, false);
					break;
				case ACTION_START_TRIBUNAL:
				{
					Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
						if (!PlayerList.isEmpty())
							for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
							{
								me->setFaction(i->GetSource()->getFaction());
								break;
							}
					
					SetEscortPaused(false);
					InitializeEvent();
					me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
					break;
				}
				case ACTION_GO_TO_SJONNIR:
					SetEscortPaused(false);
					ResetEvent();
					me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
					break;
				case ACTION_START_SJONNIR_FIGHT:
					me->setFaction(35);
					me->MonsterYell("别担心!老布莱恩替你守着背后!你们去挡着那些金属怪物, 我看能不能说动这台机器帮助你!", LANG_UNIVERSAL, 0);
					me->PlayDirectSound(14274);
					SetEscortPaused(false);
					break;
				case ACTION_SJONNIR_DEAD:
					me->MonsterYell("洛肯?!这下麻烦了...我们虽然摆平了铁矮人, 但我敢说还有一台机器还在某个鬼地方不停生产出一票又一票的铁维库人!", LANG_UNIVERSAL, 0);
					me->PlayDirectSound(14278);
					events.ScheduleEvent(EVENT_END, 14000);
					break;
				case ACTION_ENTEREVADEMODE:
					RemoveEscortState(0x7); // all states
					me->SetHomePosition(1077.41f, 474.16f, 207.8f, 2.70526f);
					me->UpdatePosition(1077.41f, 474.16f, 207.9f, 2.70526f, true);
					me->StopMovingOnCurrentPos();
					Reset();
					break;
				case ACTION_WIPE_START:
					Start(false, true, 0, 0, true, false);
					SetNextWaypoint(20, false);
					ResetEvent();
					me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
					break;
			}
		}

		void JustSummoned(Creature* cr)
		{
			if (cr->GetEntry() == NPC_ABEDNEUM || cr->GetEntry() == NPC_KADDRAK || cr->GetEntry() == NPC_MARNAK)
				cr->SetCanFly(true);
			else
				summons.Summon(cr);
		}

		void UpdateEscortAI(uint32 diff)
		{
			events.Update(diff);
			switch (events.GetEvent())
			{
				case EVENT_KADDRAK_VISUAL:
				{
					SwitchHeadVisaul(0x1, true);
					events.PopEvent();
					break;
				}
				case EVENT_MARNAK_VISUAL:
				{
					SwitchHeadVisaul(0x2, true);
					events.PopEvent();
					break;
				}
				case EVENT_ABEDNEUM_VISUAL:
				{
					SwitchHeadVisaul(0x4, true);
					events.PopEvent();
					break;
				}
				case EVENT_KADDRAK_HEAD: // First
				{
					if (Creature *kaddrak = GetKaddrak())
					{
						if (Player *plr = SelectTargetFromPlayerList(100.0f))
							kaddrak->CastSpell(plr, DUNGEON_MODE(SPELL_GLARE_OF_THE_TRIBUNAL, SPELL_GLARE_OF_THE_TRIBUNAL_H), true);
					}

					events.RescheduleEvent(EVENT_KADDRAK_SWITCH_EYE, 1500);
					events.RepeatEvent(2000+urand(0,2000));
					break;
				}
				case EVENT_KADDRAK_SWITCH_EYE:
				{
					if (Creature *kaddrak = GetKaddrak())
					{
						if (urand(0,1))
							kaddrak->UpdatePosition(927.9f, 330.9f, 219.4f, 2.4f, true);
						else
							kaddrak->UpdatePosition(923.7f, 326.9f, 219.5f, 2.1f, true);

						kaddrak->StopMovingOnCurrentPos();
					}

					events.PopEvent();
					break;
				}
				case EVENT_MARNAK_HEAD: // Second
				{
					if (Creature *marnak = GetMarnak())
					{
						if (Creature *cr = me->SummonCreature(NPC_DARK_MATTER_TRIGGER, marnak->GetPositionX(), marnak->GetPositionY(), marnak->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 7000))
						{
							cr->CastSpell(cr, SPELL_DARK_MATTER_VISUAL, true);
							if (Player *plr = SelectTargetFromPlayerList(100.0f))
							{
								float speed = me->GetDistance(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ()) / (4000.0f * 0.001f);
								cr->MonsterMoveWithSpeed(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), speed);
							}
						}
					}
					events.RepeatEvent(20000);
					break;
				}
				case EVENT_ABEDNEUM_HEAD: // Third
				{
					if (Creature *abedneum = GetAbedneum())
					{
						Player *plr = SelectTargetFromPlayerList(100.0f);
						if (!plr)
							break;

						if (Creature *cr = me->SummonCreature(NPC_SEARING_GAZE_TRIGGER, plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000))
						{
							// summon another abedneum to create double beam, despawn just after trigger despawn
							me->SummonCreature(NPC_ABEDNEUM, 897.0f, 326.9f, 223.5f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 12000);
							cr->CastSpell(cr, DUNGEON_MODE(SPELL_SEARING_GAZE, SPELL_SEARING_GAZE_H), true);
						}
					}
					events.RepeatEvent(30000);
					break;
				}
				case EVENT_SUMMON_MONSTERS:
				{
					uint32 Time = 45000 - (2500*WaveNum);
					SummonCreatures(NPC_DARK_RUNE_PROTECTOR, 3);
					if (WaveNum > 2)
						SummonCreatures(NPC_DARK_RUNE_STORMCALLER, 2);
					if (WaveNum > 5)
						SummonCreatures(NPC_IRON_GOLEM_CUSTODIAN, 1);

					WaveNum++;
					events.RepeatEvent(Time);
					break;
				}
				case EVENT_TRIBUNAL_END:
				{
					// Has to be here!
					events.Reset();
					//DespawnHeads();
					summons.DespawnAll();

					if (pInstance)
					{
						pInstance->SetData(BOSS_TRIBUNAL_OF_AGES, DONE);
						pInstance->SetData(BRANN_BRONZEBEARD, 3);
						me->CastSpell(me, 59046, true); // credit
					}

					me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
					

					// Spawn Chest and quest credit
					if (Player *plr = SelectTargetFromPlayerList(200.0f))
					{
						if (GameObject* go = plr->SummonGameObject((IsHeroic() ? GO_TRIBUNAL_CHEST_H : GO_TRIBUNAL_CHEST), 880.406f, 345.164f, 203.706f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0))
						{
							plr->RemoveGameObject(go, false);
							go->SetLootMode(1);
							go->SetUInt32Value(GAMEOBJECT_FLAGS, 0);
						}

						plr->GroupEventHappens(QUEST_HALLS_OF_STONE, me);
					}
					
					events.ScheduleEvent(EVENT_GO_TO_SJONNIR, 279000);
					break;
				}
				case EVENT_GO_TO_SJONNIR:
				{
					SetEscortPaused(false);
					ResetEvent();
					me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
					break;
				}
				case EVENT_END:
				{
					events.Reset();
					if (pInstance) 
						pInstance->SetData(BRANN_BRONZEBEARD, 6);

					me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
					me->MonsterYell("我会用熔炉制造一批土灵来防守...但咱们最大的挑战依旧存在:找到洛肯并且阻止他!", LANG_UNIVERSAL, 0);
					me->PlayDirectSound(14279);
					break;
				}
			}

			if (TalkEvent)
			{
				SpeechPause += diff;
				if (SpeechPause >= Conversation[SpeechCount].timer)
				{
					Creature* cs = NULL;
					switch (Conversation[SpeechCount].creature)
					{
						case NPC_BRANN:		cs = me; break;
						case NPC_ABEDNEUM:	cs = GetAbedneum(); break;
						case NPC_KADDRAK:	cs = GetKaddrak(); break;
						case NPC_MARNAK:	cs = GetMarnak(); break;
					}

					if (cs)
					{
						cs->MonsterYell(Conversation[SpeechCount].text, LANG_UNIVERSAL, 0);
						cs->PlayDirectSound(Conversation[SpeechCount].sound);
					}

					if (SpeechCount < 38) 
						SpeechPause = Conversation[SpeechCount++].timer;
					else
						TalkEvent = false;
				}
			}
		}
		void SummonCreatures(uint32 entry, uint8 count)
		{
			for (int i = 0; i < count; ++i)
			{
				Creature* cr = me->SummonCreature(entry, 946.5971f+urand(0,6), 383.5330f+urand(0,6), 205.9943f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
				if(cr)
				{
					cr->AI()->AttackStart(me);
					cr->AddThreat(me, 100.0f);
					cr->SetInCombatWithZone();
				}
			}
		}

		void JustDied(Unit* killer)
		{
			ResetEvent();
			if(pInstance)
			{
				if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) != DONE) 
					pInstance->SetData(BOSS_TRIBUNAL_OF_AGES, NOT_STARTED);
			}
		}
	};
};

void brann_bronzebeard::brann_bronzebeardAI::InitializeEvent()
{
	Creature* cr = NULL;
	if (cr = me->SummonCreature(NPC_KADDRAK, 923.7f, 326.9f, 219.5f, 2.1f, TEMPSUMMON_TIMED_DESPAWN, 580000))
	{
		cr->SetInCombatWithZone();
		KaddrakGUID = cr->GetGUID();
	}
	if (cr = me->SummonCreature(NPC_MARNAK, 895.974f, 363.571f, 219.337f, 5.5f, TEMPSUMMON_TIMED_DESPAWN, 580000))
	{
		cr->SetInCombatWithZone();
		MarnakGUID = cr->GetGUID();
	}
	if (cr = me->SummonCreature(NPC_ABEDNEUM, 892.25f, 331.25f, 223.86f, 0.6f, TEMPSUMMON_TIMED_DESPAWN, 580000))
	{
		cr->SetInCombatWithZone();
		AbedneumGUID = cr->GetGUID();
	}

	TalkEvent = true;

	events.Reset();
	events.ScheduleEvent(EVENT_SUMMON_MONSTERS, 21000);
	events.ScheduleEvent(EVENT_KADDRAK_HEAD, 20000);
	events.ScheduleEvent(EVENT_MARNAK_HEAD, 105000);
	events.ScheduleEvent(EVENT_ABEDNEUM_HEAD, 205000);
	events.ScheduleEvent(EVENT_TRIBUNAL_END, 315000);

	// Viusals
	events.ScheduleEvent(EVENT_KADDRAK_VISUAL, 20000);
	events.ScheduleEvent(EVENT_MARNAK_VISUAL, 105000);
	events.ScheduleEvent(EVENT_ABEDNEUM_VISUAL, 205000);
}

void brann_bronzebeard::brann_bronzebeardAI::WaypointReached(uint32 id)
{
	switch (id)
	{
		// Stop before stairs and ask to start
		case 9: 
			SetEscortPaused(true);
			me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
			if (pInstance) 
				pInstance->SetData(BRANN_BRONZEBEARD, 2);

			break;
		// In front of Console
		case 11:
			SetEscortPaused(true);
			if(pInstance)
			{
				pInstance->SetData(BOSS_TRIBUNAL_OF_AGES, IN_PROGRESS);
				if (GameObject *tribunal = ObjectAccessor::GetGameObject(*me, pInstance->GetData64(GO_TRIBUNAL_CONSOLE)))
					tribunal->SetGoState(GO_STATE_ACTIVE);
			}
			break;
		// Before Sjonnir's door
		case 27:
			if(pInstance)
			{
				if (GameObject *door = ObjectAccessor::GetGameObject(*me, pInstance->GetData64(GO_SJONNIR_DOOR)))
					door->SetGoState(GO_STATE_ACTIVE);
				if (Creature *cr = ObjectAccessor::GetCreature(*me, pInstance->GetData64(NPC_SJONNIR)))
					cr->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
			}
			break;
		case 28:
			SetEscortPaused(true);
			break;
		case 29:
			SetEscortPaused(true);
			if (pInstance)
				if (GameObject *console = ObjectAccessor::GetGameObject(*me, pInstance->GetData64(GO_SJONNIR_CONSOLE)))
					console->SetGoState(GO_STATE_ACTIVE);

			break;
	}
}

class dark_rune_protectors : public CreatureScript
{
public:
    dark_rune_protectors() : CreatureScript("dark_rune_protectors") { }

    CreatureAI* GetAI(Creature* pCreature) const
    {
        return new dark_rune_protectorsAI (pCreature);
    }

	struct dark_rune_protectorsAI : public ScriptedAI
	{
		dark_rune_protectorsAI(Creature *c) : ScriptedAI(c)	{ }

		EventMap events;
		void Reset() 
		{
			events.Reset();
		}

		void EnterCombat(Unit *)
		{
			events.ScheduleEvent(EVENT_DRP_CHARGE, 10000);
			events.ScheduleEvent(EVENT_DRP_CLEAVE, 7000);
		}

		void UpdateAI(uint32 diff)
		{
			if (!UpdateVictim())
				return;		

			events.Update(diff);
			if (me->HasUnitState(UNIT_STATE_CASTING))
				return;

			switch (events.GetEvent())
			{
				case EVENT_DRP_CHARGE:
				{
					if (Unit *tgt = SelectTarget(SELECT_TARGET_RANDOM, 0))
						me->CastSpell(tgt, SPELL_DRP_CHARGE, false);

					events.RepeatEvent(10000);
					break;
				}
				case EVENT_DRP_CLEAVE:
				{
					me->CastSpell(me->GetVictim(), SPELL_DRP_CLEAVE, false);
					events.RepeatEvent(7000);
					break;
				}
			}

			DoMeleeAttackIfReady();
		}
	};
};

class dark_rune_stormcaller : public CreatureScript
{
public:
    dark_rune_stormcaller() : CreatureScript("dark_rune_stormcaller") { }

    CreatureAI* GetAI(Creature* pCreature) const
    {
        return new dark_rune_stormcallerAI (pCreature);
    }

	struct dark_rune_stormcallerAI : public ScriptedAI
	{
		dark_rune_stormcallerAI(Creature *c) : ScriptedAI(c) { }

		EventMap events;
		void Reset() 
		{
			events.Reset();
		}

		void EnterCombat(Unit *)
		{
			events.ScheduleEvent(EVENT_DRS_LIGHTNING_BOLD, 5000);
			events.ScheduleEvent(EVENT_DRS_SHADOW_WORD_PAIN, 12000);
		}

		void UpdateAI(uint32 diff)
		{
			if (!UpdateVictim())
				return;

			events.Update(diff);
			if (me->HasUnitState(UNIT_STATE_CASTING))
				return;

			switch (events.GetEvent())
			{
				case EVENT_DRS_LIGHTNING_BOLD:
				{
					me->CastSpell(me->GetVictim(), IsHeroic() ? SPELL_DRS_LIGHTING_BOLT_H : SPELL_DRS_LIGHTING_BOLT, false);
					events.RepeatEvent(5000);
					break;
				}
				case EVENT_DRS_SHADOW_WORD_PAIN:
				{
					me->CastSpell(me->GetVictim(), IsHeroic() ? SPELL_DRS_SHADOW_WORD_PAIN_H : SPELL_DRS_SHADOW_WORD_PAIN, false);
					events.RepeatEvent(12000);
					break;
				}
			}

			DoMeleeAttackIfReady();
		}
	};
};

class iron_golem_custodian : public CreatureScript
{
public:
    iron_golem_custodian() : CreatureScript("iron_golem_custodian") { }

    CreatureAI* GetAI(Creature* pCreature) const
    {
        return new iron_golem_custodianAI (pCreature);
    }

	struct iron_golem_custodianAI : public ScriptedAI
	{
		iron_golem_custodianAI(Creature *c) : ScriptedAI(c) { }
		EventMap events;
		void Reset() 
		{
			events.Reset();
		}
		
		void EnterCombat(Unit *)
		{
			events.ScheduleEvent(EVENT_IGC_CRUSH, 6000);
			events.ScheduleEvent(EVENT_IGC_GROUND_SMASH, 4000);
		}
		void UpdateAI(uint32 diff)
		{
			if (!UpdateVictim())
				return;

			events.Update(diff);
			if (me->HasUnitState(UNIT_STATE_CASTING))
				return;

			switch (events.GetEvent())
			{
				case EVENT_IGC_CRUSH:
				{
					me->CastSpell(me->GetVictim(), SPELL_IGC_CRUSH_ARMOR, false);
					events.RepeatEvent(6000);
					break;
				}
				case EVENT_IGC_GROUND_SMASH:
				{
					me->CastSpell(me->GetVictim(), IsHeroic() ? SPELL_IGC_GROUND_SMASH_H : SPELL_IGC_GROUND_SMASH, false);
					events.RepeatEvent(5000);
					break;
				}
			}

			DoMeleeAttackIfReady();
		}
	};
};

class spell_hos_dark_matter : public SpellScriptLoader
{
    public:
        spell_hos_dark_matter() : SpellScriptLoader("spell_hos_dark_matter") { }

		class spell_hos_dark_matter_AuraScript : public AuraScript
		{
			PrepareAuraScript(spell_hos_dark_matter_AuraScript);

			void HandleEffectRemove(AuraEffect const * /*aurEff*/, AuraEffectHandleModes /*mode*/)
			{
				if (Unit *caster = GetCaster())
					caster->CastSpell(caster, caster->GetMap()->IsHeroic() ? SPELL_DARK_MATTER_H : SPELL_DARK_MATTER, true);
			}

			void Register()
			{
				OnEffectRemove += AuraEffectRemoveFn(spell_hos_dark_matter_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
			}
		};

		AuraScript *GetAuraScript() const
		{
			return new spell_hos_dark_matter_AuraScript();
		}
};

void AddSC_brann_bronzebeard()
{
	new brann_bronzebeard();
	new dark_rune_protectors();
	new dark_rune_stormcaller();
	new iron_golem_custodian();
	new spell_hos_dark_matter();
}
